package com.zhida.smartcontrol.knet;

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jay.tools.utils.EventBusUtils;
import com.jay.tools.utils.LogUtil;
import com.jay.tools.utils.SharedUtil;
import com.yanzhenjie.kalle.FileBinary;
import com.yanzhenjie.kalle.JsonBody;
import com.yanzhenjie.kalle.Kalle;
import com.yanzhenjie.kalle.Params;
import com.yanzhenjie.kalle.ProgressBar;
import com.yanzhenjie.kalle.exception.ConnectTimeoutError;
import com.yanzhenjie.kalle.exception.HostError;
import com.yanzhenjie.kalle.exception.NetworkError;
import com.yanzhenjie.kalle.exception.ParseError;
import com.yanzhenjie.kalle.exception.ReadTimeoutError;
import com.yanzhenjie.kalle.exception.URLError;
import com.yanzhenjie.kalle.exception.WriteException;
import com.yanzhenjie.kalle.simple.Callback;
import com.yanzhenjie.kalle.simple.SimpleBodyRequest;
import com.yanzhenjie.kalle.simple.SimpleResponse;
import com.yanzhenjie.kalle.simple.SimpleUrlRequest;
import com.zhida.smartcontrol.common.Api;
import com.zhida.smartcontrol.common.Keys;
import com.zhida.smartcontrol.launch.login.bean.LoginBean;
import com.zhida.smartcontrol.mvp.BaseView;

import java.io.File;
import java.nio.charset.Charset;
import java.util.Timer;
import java.util.TimerTask;

public class KalleCenter {

    private String mTag;
    private BaseView mView;
    private boolean isMap; //请求是否来源于百度地图接口

    public KalleCenter(String tag, BaseView view) {
        this.mTag = tag;
        this.mView = view;
    }

    public void postJson(String url, Object object, boolean showLoading, final KalleCallBack callBack) {
        SimpleBodyRequest.Api request = Kalle.post(Api.BASE_URL + url);
        if (null != object) {
            String json = JSON.toJSONString(object);
            LogUtil.e(mTag, "发送：" + json);
            request.body(new JsonBody(json, Charset.forName("UTF-8")));
        }
        String token = SharedUtil.getString(Keys.TOKEN, "");
        if (!TextUtils.isEmpty(token)) {
            request.setHeader("X-Access-Token", token);
        }

        request.perform(new MyCallBack(callBack, showLoading));
    }

    public void postJson(String url, Object object, boolean showLoading, long time, final KalleCallBack callBack) {
        SimpleBodyRequest.Api request = Kalle.post(Api.BASE_URL + url);
        if (null != object) {
            String json = JSON.toJSONString(object);
            LogUtil.e(mTag, "发送：" + json);
            request.body(new JsonBody(json, Charset.forName("UTF-8")));
        }
        String token = SharedUtil.getString(Keys.TOKEN, "");
        if (!TextUtils.isEmpty(token)) {
            request.setHeader("X-Access-Token", token);
        }

        request.perform(new MyCallBack(callBack, showLoading, time));
    }

    public void get(String url, Params params, boolean showLoading, final KalleCallBack callBack) {
        get(url, params, false, showLoading, callBack);
    }

    // isMap是否来源于地图搜索
    public void get(String url, Params params, boolean isMap, boolean showLoading, final KalleCallBack callBack) {
        this.isMap = isMap;
        SimpleUrlRequest.Api request = Kalle.get(isMap ? url : Api.BASE_URL + url);
        request.tag(mTag);
        if (null != params) {
            request.params(params);
        }
        String token = SharedUtil.getString(Keys.TOKEN, "");
        if (!TextUtils.isEmpty(token) && !isMap) {
            request.setHeader("X-Access-Token", token);
        }
        request.perform(new MyCallBack(callBack, showLoading));
    }

    public void delete(String url, Params params, boolean showLoading, final KalleCallBack callBack) {
        String str = params.toString(false);
        String urlStr = isMap ? url : Api.BASE_URL + url;
        SimpleBodyRequest.Api delete = Kalle.delete(urlStr + "?" + str);
        delete.tag(mTag);
        String token = SharedUtil.getString(Keys.TOKEN, "");
        if (!TextUtils.isEmpty(token) && !isMap) {
            delete.setHeader("X-Access-Token", token);
        }
        delete.perform(new MyCallBack(callBack, showLoading));
    }

    public void putJson(String url, Object object, boolean showLoading, final KalleCallBack callBack) {
        SimpleBodyRequest.Api put = Kalle.put(isMap ? url : Api.BASE_URL + url);
        put.tag(mTag);
        String token = SharedUtil.getString(Keys.TOKEN, "");
        if (!TextUtils.isEmpty(token) && !isMap) {
            put.setHeader("X-Access-Token", token);
        }
        put.body(new JsonBody(JSON.toJSONString(object), Charset.forName("UTF-8")));
        put.perform(new MyCallBack(callBack, showLoading));
    }

    public void post(String url, Params params, boolean showLoading, final KalleCallBack callBack) {
        Kalle.post(url)
                .tag(mTag)
                .setParams(params)
                .perform(new MyCallBack(callBack, showLoading));
    }

    public void upLoad(String url, String filePath, boolean showLoading, final KalleCallBack callBack) {
        FileBinary binary = new FileBinary(new File(filePath));
        binary.onProgress(new ProgressBar<FileBinary>() {
            @Override
            public void progress(FileBinary origin, int progress) {
                LogUtil.e(mTag, "上传进度：" + progress);
            }
        });
        SimpleBodyRequest.Api post = Kalle.post(Api.BASE_URL + url);
        post.tag(mTag);

        String token = SharedUtil.getString(Keys.TOKEN, "");
        if (!TextUtils.isEmpty(token) && !isMap) {
            post.setHeader("X-Access-Token", token);
        }

        post.param("Content-Type", binary.contentType())
                .binary("file", binary)
                .perform(new MyCallBack(callBack, showLoading));
    }


    private class MyCallBack extends Callback<String, String> {
        private boolean showLoading = true;
        private long time = 0;
        private KalleCallBack mCallBack;

        @SuppressLint("HandlerLeak")
        private Handler timeHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 1) {
                    hideLoading();
                }
            }
        };

        public void setTimer() {
            Timer timer = new Timer();
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                    timer.cancel();
                    Message message = Message.obtain();
                    message.what = 1;
                    timeHandler.sendMessage(message);
                }
            };
            timer.schedule(task, time, time);
        }

        public MyCallBack(KalleCallBack callBack, boolean showLoading) {
            this.mCallBack = callBack;
            this.showLoading = showLoading;
        }

        public MyCallBack(KalleCallBack callBack, boolean showLoading, long time) {
            this.mCallBack = callBack;
            this.showLoading = showLoading;
            this.time = time;
        }

        @Override
        public void onStart() {
            if (showLoading)
                showLoading();
//            if (time > 0)
//                setTimer();
        }

        @Override
        public void onResponse(SimpleResponse<String, String> response) {
            doSuccess(response, mCallBack);
            if (showLoading)
                hideLoading();
        }

        @Override
        public void onException(Exception e) {
            doException(e, mCallBack);
            if (showLoading)
                hideLoading();
        }

        @Override
        public void onCancel() {
            LogUtil.d(mTag, "post请求已取消");
            if (showLoading)
                hideLoading();
        }

        @Override
        public void onEnd() {
            if (showLoading)
                hideLoading();
        }
    }

    /**
     * TODO 成功
     */
    private void doSuccess(SimpleResponse<String, String> response, KalleCallBack callBack) {
        if (!response.isSucceed()) {
            callBack.onFailed("请求数据失败，请重试");
            return;
        }

        String json = response.succeed();
        LogUtil.d(mTag, "请求结果：" + json);

        if (isMap) {
            if (response.code() == 200) {
                callBack.onSuccess(json, "");
            } else {
                callBack.onFailed("没有找到相关地址");
            }
            return;
        }

        if (json.contains("TOKEN_INVALID")) {
//        {"timestamp":"2019-11-23 07:49:59","status":500,"error":"Internal Server Error","message":"org.apache.shiro.authc.AuthenticationException: TOKEN_INVALID","path":"/zwzm/project/add"}
            SharedUtil.putString(Keys.TOKEN, "");
            callBack.onFailed("请重新登录");
            EventBusUtils.post(new LoginBean());
            return;
        }

        if (response.code() != 200) {
            callBack.onFailed("请求数据失败，请重试");
            return;
        }

        JSONObject jsonObject = JSON.parseObject(json);
        String message = jsonObject.getString("message");
        if (jsonObject.getBooleanValue("success")) {
            if (jsonObject.getIntValue("code") == 200) {
                callBack.onSuccess(jsonObject.getString("result"), message);
            } else {
                callBack.onFailed(message);
            }
            return;
        }
        callBack.onFailed(message);
    }

    /**
     * TODO 处理异常
     */
    private void doException(Exception e, KalleCallBack callBack) {
        String message;
        if (e instanceof NetworkError) {
            message = "网络不可用";
        } else if (e instanceof URLError) {
            message = "Url格式错误";
        } else if (e instanceof HostError) {
            message = "没有找到Url指定服务器";
        } else if (e instanceof ConnectTimeoutError) {
            message = "连接服务器超时，请重试";
        } else if (e instanceof WriteException) {
            message = "发送数据错误，请检查网络";
        } else if (e instanceof ReadTimeoutError) {
            message = "读取服务器数据超时，请检查网络";
        } else if (e instanceof ParseError) {
            message = "解析数据时发生异常";
        } else {
            message = "发生未知异常，请稍后重试";
        }
        callBack.onFailed(message);
    }

    public void cancel() {
        Kalle.cancel(mTag);
    }

    private void showLoading() {
        if (null != mView)
            mView.showLoading("");
    }

    private void hideLoading() {
        if (null != mView)
            mView.hideLoading();
    }

}
